# Reksio - Memory Map Editor
# Copyright (C) 2023 CERN
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <https://www.gnu.org/licenses/>.
#
# In applying this licence, CERN does not waive the privileges and immunities
# granted to it by virtue of its status as an Intergovernmental Organization or
# submit itself to any jurisdiction.

from collections.abc import MutableMapping


class TreeView(MutableMapping):
    def __init__(self, yaml_tree, root_node, parent=None, global_root=False):
        self.tree = yaml_tree
        self.node_type = root_node
        self.parent = parent
        self.global_root = global_root

    @property
    def attributes(self):
        return self.tree[self.node_type]

    @property
    def children(self):
        children = self.attributes.get('children', [])
        return iter([TreeView(child, list(child)[0], self) for child in children])

    @property
    def root(self):
        if self.parent is None:
            return self
        parent = self.parent
        while getattr(parent, 'parent', None):
            parent = parent.parent
        return parent

    def walk_pre_order(self):
        if self.parent is None:
            yield self
        for child in self.children:
            yield child
        for child in self.children:
            yield from child.walk_pre_order()

    def walk_post_order(self):
        for child in self.children:
            yield from child.walk_post_order()
        yield self

    def is_global_root(self):
        """
        Returns true only for the main-top memory map
        """
        return self.global_root

    def __iter__(self):
        return iter(self.attributes)

    def __len__(self):
        return len(self.attributes)

    def __getitem__(self, item):
        return self.attributes[item]

    def __setitem__(self, key, value):
        self.attributes[key] = value

    def __delitem__(self, key):
        del self.attributes[key]

    def __str__(self):
        return f"TreeView({self.node_type}, parent={self.parent})"

    def __repr__(self):
        return f"{str(self)}: {self.attributes}"
